package com.handinfo.android.core.graphics.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLUtils;

import com.handinfo.android.utils.Tools;

public class Texture2D
{
	private int m_id;
	private Bitmap m_bitmap;
	private float m_width, m_height;
	private float m_valid_width, m_valid_height;
	private float m_maxS, m_maxT;
	private FloatBuffer m_vertexes, m_texCoords;
	private int[] m_textureIV = { 0, 0, 48, 48 };

	public Texture2D(Bitmap bitmap)
	{
		m_bitmap = updateBitmap(bitmap);
		init();
	}

	public Texture2D(Bitmap bitmap, Rect region)
	{
		m_bitmap = updateBitmap(bitmap, region);
		init();
	}

	private Bitmap updateBitmap(Bitmap bitmap)
	{
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		int pow2Width = Tools.pow2(width);
		int pow2Height = Tools.pow2(height);

		m_maxS = width / (float) pow2Width;
		m_maxT = height / (float) pow2Height;

		//尺寸满足2的N次幂直接返回
		if (width == pow2Width && height == pow2Height)
			return bitmap;

		Bitmap bmp = Bitmap.createBitmap(pow2Width, pow2Height,
				bitmap.hasAlpha() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bmp);
		canvas.drawBitmap(bitmap, 0, 0, null);
		return bmp;
	}

	private Bitmap updateBitmap(Bitmap bitmap, Rect region)
	{
		int width = region.right - region.left;
		int height = region.bottom - region.top;

		int pow2Width = Tools.pow2(width);
		int pow2Height = Tools.pow2(height);

		m_maxS = width / (float) pow2Width;
		m_maxT = height / (float) pow2Height;

		Bitmap bmp = Bitmap.createBitmap(pow2Width, pow2Height,
				bitmap.hasAlpha() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);

		Canvas canvas = new Canvas(bmp);
		canvas.clipRect(0, 0, width, height);
		canvas.drawBitmap(bitmap, -region.left, -region.top, null);
		return bmp;
	}

	public void init()
	{
		m_width = m_bitmap.getWidth();
		m_height = m_bitmap.getHeight();
		m_valid_width = m_width * m_maxS;
		m_valid_height = m_height * m_maxT;

		ByteBuffer vfb = ByteBuffer.allocateDirect(4 * 3 * 4);
		vfb.order(ByteOrder.nativeOrder());
		m_vertexes = vfb.asFloatBuffer();

		ByteBuffer tfb = ByteBuffer.allocateDirect(4 * 2 * 4);
		tfb.order(ByteOrder.nativeOrder());
		m_texCoords = tfb.asFloatBuffer();

//		float[] texCoords = {0.0f, m_maxT,
//				m_maxS, m_maxT,
//				0.0f, 0.0f,
//				m_maxS, 0.0f};

		float[] texCoords = { 0.0f, 0.0f,
				m_maxS, 0.0f,
				0.0f, m_maxT,
				m_maxS, m_maxT };
		m_texCoords.put(texCoords);
		m_texCoords.position(0);
	}

	public void loadTexture(GL10 gl)
	{
		if (m_id == 0) {
			int[] textures = new int[1];
			gl.glGenTextures(1, textures, 0);
			m_id = textures[0];
			gl.glBindTexture(GL10.GL_TEXTURE_2D, m_id);
			gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
			gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, m_bitmap, 0);
			m_bitmap.recycle();
		}
	}

	public void draw(GL10 gl, RectF rect)
	{
		gl.glEnable(GL10.GL_TEXTURE_2D);

		loadTexture(gl);

//		float l = (rect.left - (800 >> 1));
//		float t = (rect.top - (480 >> 1));
//		float r = (rect.right - (800 >> 1));
//		float b = (rect.bottom - (480 >> 1));

//		float l = rect.left;
//		float t = -rect.bottom;
//		float r = rect.right;
//		float b = -rect.top;

//		float[] vertexes = { point.x / 800f, point.y / 480f, 0.0f,
//				(m_valid_width + point.x) / 800f, point.y / 480f, 0.0f,
//				point.x / 800f, (m_valid_height + point.y) / 480f, 0.0f,
//				(m_valid_width + point.x) / 800f, (m_valid_height + point.y) / 480f, 0.0f };

//		float[] vertexes = { point.x, point.y, 0.0f,
//				m_valid_width + point.x, point.y, 0.0f,
//				point.x, m_valid_height + point.y, 0.0f,
//				m_valid_width + point.x, m_valid_height + point.y, 0.0f };

//		float[] vertexes = { 0 - 1f, 0 - 1f, 0.0f,
//				m_valid_width / 800 - 1f, 0 - 1f, 0.0f,
//				0 - 1f, m_valid_height / 480 - 1f, 0.0f,
//				m_valid_width / 800 - 1f, m_valid_height / 480 - 1f, 0.0f };

//		float[] vertexes = { l, t, 0,
//				r, t, 0,
//				l, b, 0, 
//				r, b, 0};

//		m_vertexes.put(vertexes);
//		m_vertexes.position(0);

		gl.glBindTexture(GL10.GL_TEXTURE_2D, m_id);
		((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, m_textureIV, 0);
		((GL11Ext) gl).glDrawTexfOES(100, 100, 0, 64, 64);

//        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//
//        gl.glBindTexture(GL10.GL_TEXTURE_2D, m_id);
//        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_vertexes);
//        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, m_texCoords);
//        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//        
//        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//
		gl.glDisable(GL10.GL_TEXTURE_2D);
	}

	public void draw(GL10 gl, PointF point)
	{

	}

	public void draw(GL10 gl, RectF src, RectF dest)
	{

	}

	public void draw(GL10 gl, float srcX, float srcY, float srcW, float srcH, float destX, float destY, float destW,
			float destH)
	{

	}
}
